﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing;
using System.Dynamic;
using System.Linq;
using System.Runtime.Serialization;
using DependencyAnalysis.Serialization;

namespace theeg.DependencyAnalysis.Retrospective
{
    [Serializable]
    public class JsonSerializableExpandoObject : DynamicObject, IJsonSerializable, IReportObject
    {
        private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();

        public string Name { get; set; }

        public string TypeName { get; set; }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            foreach (var pair in _properties)
            {
                if (pair.Value == null) continue;
                info.AddValue(pair.Key, pair.Value);
            }
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            _properties.TryGetValue(binder.Name, out result);
            return true;
        }

        public void Set(string key, object value)
        {
            _properties[key] = value;
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            _properties[binder.Name] = value;
            return true;
        }

        public void WriteJson(JsonWriter writer)
        {
            writer.WriteStartElement();
            writer.WriteStartAttribute("Name");
            writer.WriteValue(Name);
            writer.WriteEndAttribute();
            writer.WriteStartAttribute("TypeName");
            writer.WriteValue(TypeName);
            writer.WriteEndAttribute();
            var keyValuePairs = _properties.Where(x => x.Key != null).ToArray();
            for (int index = 0; index < keyValuePairs.Length; index++)
            {
                var pair = keyValuePairs[index];

                writer.WriteStartAttribute(pair.Key);
                writer.WriteValue(pair.Value);
                if (index < keyValuePairs.Length - 1)
                {
                    writer.WriteEndAttribute();
                }
            }
            writer.WriteEndElement();
        }
    }
}